/*--------------------------------------------------------------------------------
* Copyright (c) 2022,西北农林科技大学信息学院计算机科学系
* All rights reserved.
*
* 文件名称：main.c
* 文件标识：见配置管理计划书
* 摘要：生成EXCEL表格列名称字符串。
* 题目：EXCEL的列名称由类似A, B, C, ..., Z, AA, AB, AC, ..., AZ,
*       BA, BB, ..., ZZ, AAA, AAB,...等这样的字符串构成。
*
*       假设从0开始计数，则列0对应"A", 列1对应"B"，而列26对应"AA"。
*
*       请编写函数将指定的列编号转换为字符串表示的列名称，要求函数原型为：
*           char* get_excel_column_name(char *col_name, int idx);
*       其输入/输出关系如：
*       Input          Output
*        26             Z
*        51             AY
*        52             AZ
*        80             CB
*        676            YZ
*        702            ZZ
*        705            AAC
*       几个典型值为：
*       Z              26
*       ZZ             702
*       ZZZ            18278
*       ZZZZ           475254
*       ZZZZZ          12356630
*
*
* 当前版本：1.0
* 作者：耿楠
* 完成日期：2022年12月13日
*
* 取代版本：无
* 原作者：
* 完成日期：
--------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 列名称最大长度(字符数) */
#define MAXLEN 8

/* 函数原型 */
char* get_excel_column_name(char *, int);

int main()
{
    char str[MAXLEN] = {0};
    int idx[] = {26, 51, 52, 80, 676, 701, 702, 705, 18278, 475254, 12356630};
    int i;

    for(i = 0; i < sizeof(idx) / sizeof(idx[0]); i++)
    {
        memset(str, 0, MAXLEN);
        printf("%d---->%s\n", idx[i], get_excel_column_name(str, idx[i]));
    }

    return 0;
}

/*--------------------------------------------------------------------
// 名称：char* get_excel_column_name(char *col_name, int idx)
// 功能：根据传入的列编号生成EXCEL的列名称
// 参数：
//       [char *col_name] --- 结果字符串指针(需要有空间可写)
//       [int idx] ---------- 从1开始计数的excel列编号
// 返回：[char*] --- 结果字符串指针
// 作者：耿楠
// 日期：2022年12月14日
// 参考：https://www.w3resource.com/c-programming-exercises/math/c-math-exercise-8.php
---------------------------------------------------------------------*/
char *get_excel_column_name(char *col_name, int idx)
{
    int i;
    int len = 0;

    do
    {
        /* 向后移动一位(逆序) */
        for(i = len; i > 0; i --)
        {
            col_name[i] = col_name[i - 1];
        }

        /* 取余偏移得到当前余数对应字符 */
        col_name[0] = ((idx - 1) % 26) + 'A';
        /* 准备高一位 */
        idx = (idx - 1) / 26;

        /* 计数 */
        len++;
    }while(idx > 0);

    /* 字符串终止符 */
    col_name[len] = '\0';

    return col_name;
}
